home *** CD-ROM | disk | FTP | other *** search
/ MACD 5 / MACD 5.bin / workbench / libs / unixlib.lha / unix / test / exec_test2.c < prev    next >
C/C++ Source or Header  |  1996-07-07  |  2KB  |  105 lines

  1. /* test program for exec() in unix.lib
  2.  *
  3.  * Launches as a child a program specified on the command line, redirecting
  4.  * its standard output (by mean of dup2()) to the write end of a pipe,
  5.  * attaches a stream to the read end of the pipe to read the child output,
  6.  * reopens stdout towards the console. The standard input is left indisturbed,
  7.  * so the child reads from the console and writes to the pipe.
  8.  */
  9.  
  10. #include <stdio.h>
  11. #include <errno.h>
  12. #include <stdlib.h>
  13. #include <unistd.h>
  14. #include <sys/wait.h>
  15.  
  16. typedef unsigned char bool;
  17.  
  18. #define FALSE 0
  19. #define TRUE  1
  20.  
  21. char *program;
  22.  
  23. void
  24. LogFatal(char *x0, char *x1)
  25. {
  26.     extern char *sys_errlist[];
  27.     static bool entered = FALSE;
  28.  
  29.     if (entered)
  30.         return;
  31.     entered = TRUE;
  32.  
  33.     fprintf(stderr, "%s: ", program);
  34.     if (errno)
  35.         fprintf(stderr, "%s: ", sys_errlist[ errno ]);
  36.     fprintf(stderr, x0,x1);
  37.     fprintf(stderr, "  Stop.\n");
  38.     exit(20);
  39. }
  40.  
  41. void
  42. LogFatalI(char *s, int i)
  43. {
  44.     /*NOSTRICT*/
  45.     LogFatal(s, (char *)i);
  46. }
  47.  
  48. int
  49. main(int ac, char **av)
  50. {
  51.     int pid, status;
  52.     int p_io[2];
  53.     char *comm;
  54.     char *argv[3];
  55.     FILE *infp;
  56.  
  57.     if (ac < 2 | ac > 3) {
  58.         fprintf(stderr, "Usage: %s test-program [arg]\n", av[0]);
  59.         exit(EXIT_FAILURE);
  60.     }
  61.  
  62.     program = av[0];
  63.     comm = av[1];
  64.     argv[0] = av[1];
  65.     argv[1] = av[2];
  66.     argv[2] = NULL;
  67.  
  68.     /* The exec() function in unix.lib starts a child process. */
  69.     /* It is possible to give the child input, output, current */
  70.     /* dir and stack different from the parent. If the input   */
  71.     /* or the output of the child are changed, they are closed */
  72.     /* after the child exits. Exec() returns the child pid.    */
  73.  
  74.     if (pipe(p_io) != 0)
  75.         LogFatal("Cannot get a pipe.", "");
  76.  
  77.     if (!(infp = fdopen(p_io[0], "r")))
  78.         LogFatal("Cannot attach a stream to pipe.", "");
  79.  
  80.     dup2(p_io[1], 1);
  81.     pid = exec(comm, argv, -1, -1, NULL, 50000);
  82.     close(p_io[1]);
  83.     freopen("console:", "w", stdout);
  84.     if (pid < 0)
  85.         LogFatal("Cannot exec %s.", comm);
  86.  
  87.     printf("child output (char, ascii): ");
  88.     while(!feof(infp)) {
  89.         char c = getc(infp);
  90.         printf("(%c,%d)", c, c);
  91.     }
  92.     printf("\n");
  93.     fclose(infp);
  94.  
  95.     /* Simply wait child completion */
  96.     if (wait(&status) > 0) {
  97.         if (WIFSIGNALED(status))
  98.             LogFatalI("Signal %d.", WTERMSIG(status));
  99.         if (WIFEXITED(status) && WEXITSTATUS(status))
  100.             LogFatalI("Exit code %d.", WEXITSTATUS(status));
  101.     }
  102.  
  103.     return(WEXITSTATUS(status));
  104. }
  105.